package com.calvin.study.config;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.Filter;

import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.calvin.study.shiro.CustomerAuthorizationFilter;
import com.calvin.study.shiro.CustomerRealm;
import com.calvin.study.shiro.RedisCacheManager;

@Configuration
public class ShiroConfig {

	// 1.创建shiroFilter
	@Bean
	public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager) {

		ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
		// 给filter设置安全管理器
		shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
		
		shiroFilterFactoryBean.setLoginUrl("/login.html");
		shiroFilterFactoryBean.setSuccessUrl("/");
		shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized.html");
		
		Map<String, Filter> filters = new HashMap<>();
		filters.put("permFilter", customerAuthorizationFilter());
		shiroFilterFactoryBean.setFilters(filters);
		 
		Map<String, String> map = new HashMap<String, String>();
		// 配置系统公共资源
		map.put("/login.html", "anon");// anon 设置为公共资源
		map.put("/login", "anon");// anon 设置为公共资源
		map.put("/register.html", "anon");// anon 设置为公共资源
		map.put("/register", "anon");// anon 设置为公共资源
		map.put("/getVerifyCode","anon");//验证码
		// ...
		
		// 配置系统受限资源
		map.put("/**", "authc");// authc 请求这个资源需要认证和授权
		map.put("/", "permFilter");
		map.put("/syslog", "permFilter");
		map.put("/sysuser", "permFilter");
		map.put("/biz1", "permFilter");
		map.put("/biz2", "permFilter");
		shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
		
		return shiroFilterFactoryBean;
	}

	// 2.创建安全管理器
	@Bean
	public DefaultWebSecurityManager getDefaultWebSecurityManager(Realm realm) {
		DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
		// 给安全管理器设置
		defaultWebSecurityManager.setRealm(realm);
		return defaultWebSecurityManager;
	}

	// 3.创建自定义realm
	@Bean
	public Realm getRealm(CredentialsMatcher credentialsMatcher) {
		CustomerRealm realm = new CustomerRealm();
		realm.setCredentialsMatcher(credentialsMatcher);
		
		realm.setCachingEnabled(true);
		realm.setAuthenticationCachingEnabled(true);
		//自定义认证缓存名称，如果不自定义则以当前realm类全路径作为名称
		realm.setAuthenticationCacheName("authenticationCache");
		realm.setAuthorizationCachingEnabled(true);
		////自定义授权缓存名称
		realm.setAuthorizationCacheName("authorizationCache");
		realm.setCacheManager(new RedisCacheManager());
		return realm;
	}

	@Bean
	public HashedCredentialsMatcher credentialsMatcher() {
		HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
		credentialsMatcher.setHashAlgorithmName("md5");
		return credentialsMatcher;
	}

	@Bean
	public CustomerAuthorizationFilter customerAuthorizationFilter() {
		return new CustomerAuthorizationFilter();
	}
}
